<?php

class ListTask extends Task {
    public function __construct($argv) {
        parent::__construct($argv);
        $this->description = "Lists the tasks and their brief description.";
        $this->example = <<<EXAMPLE
ex. mini list
This will list all of the tasks available.

ex. mini list --tag=misc
This will list all of the tasks with tag misc.

ex. mini list --tag=db,misc
This will list all of the tasks with tag db and misc.

ex. mini list --tags
This will list all of the tags.

ex. mini list --bytags
This will list all of the tasks grouped by tag.
EXAMPLE;
    }

    public function before() {
        $tasksMap = array_flip(Task::get_available_tasks($this->argv));

        $taskNameLength = 0;
        $allTasks = array();
        $allTags = array();
        foreach ($tasksMap as $task => $valid) {
            $taskInstance = Task::get_instance($task);
            $allTasks[$task] = $taskInstance;
            $allTags[$task] = $taskInstance->tags;
            if (strlen($task) > $taskNameLength) {
              $taskNameLength = strlen($task);
            }
        }

        $taskNameLength = $taskNameLength <= 25 ? 25 : $taskNameLength + 4;
        $this->taskNameLength = $taskNameLength;

        $this->allTasks = $allTasks;
        $this->allTags = $allTags;
        $this->taskFormat = "%{$taskNameLength}s - %s\n";

        $tagNameLength = 0;
        $allUniqueTags = array();
        foreach ($this->allTags as $task => $tags) {
            foreach ($tags as $tag) {
                if (!isset($allUniqueTags[$tag])) {
                    $allUniqueTags[$tag] = array($task);
                } else {
                    $allUniqueTags[$tag][]= $task;
                }

                if (strlen($tag) > $tagNameLength) {
                  $tagNameLength = strlen($tag);
                }
            }
        }
        ksort($allUniqueTags);

        $tagNameLength = $tagNameLength <= 25 ? 25 : $tagNameLength + 4;
        $this->tagNameLength = $tagNameLength;

        $this->allUniqueTags = $allUniqueTags;
        $this->tagFormat = "%{$tagNameLength}s (%s)\n";
    }

    public function main() {
        if (isset($this->argv['tags'])) { // list all of the tags available
            $this->display_tags();
        } else if (isset($this->argv['tag'])) { // list all of the tasks with tag
            $this->display_tasks_with_tag();
        } else if (isset($this->argv['bytags'])) { // list all of the tasks grouped by tag
            $this->display_tasks_by_tag();
        } else {
            $this->display_tasks();
        }
    }

    private function display_tags() {
        foreach ($this->allUniqueTags as $tag => $tasks) {
            printf($this->tagFormat, $tag, count($tasks));
        }
    }

    private function display_tasks_with_tag() {
        if (empty($this->argv['tag']) || $this->argv['tag'] === true) {
            Task::help(array('taskInstance' => $this));
        } else {
            $tags = split(',', $this->argv['tag']);
        }

        $tasks = array();

        foreach ($tags as $tag) {
            if (isset($this->allUniqueTags[$tag])) {
                $tasks = array_merge($tasks, $this->allUniqueTags[$tag]);
            }
        }

        $tasks = array_unique($tasks);

        foreach ($tasks as $task) {
            $taskInstance = $this->allTasks[$task];
            printf($this->taskFormat, $task, $taskInstance->description);
        }
    }

    private function display_tasks_by_tag() {
        foreach ($this->allUniqueTags as $tag => $tasks) {
            printf($this->tagFormat, $tag, count($tasks));
            foreach ($tasks as $task) {
                printf("%{$this->tagNameLength}s - %s\n", "", $task);
            }
        }
    }

    private function display_tasks() {
        foreach ($this->allTasks as $task => $taskInstance) {
            printf($this->taskFormat, $task, $taskInstance->description);
        }
    }
}